package io.modifier.basic.compose.widget.annotatedtext

import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.modifier.basic.compose.theme.AppTheme
import io.modifier.basic.compose.theme.AppThemeHolder
import java.util.regex.Pattern

//<editor-fold desc="preview">

@Composable
private fun PreviewT() {
    AppTheme {
        Column(Modifier, verticalArrangement = Arrangement.spacedBy(15.dp)) {
            AnnotatedTextTest()
        }
    }
}

@Preview(backgroundColor = 0xFF121212, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Composable
private fun PreviewLightT() {
    PreviewT()
}

@Preview(backgroundColor = 0xFFf5f5f5, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewDarkT() {
    PreviewT()
}

//</editor-fold>

@Composable
fun AnnotatedText(
    modifier: Modifier = Modifier,
    text: String,
    textStyle: TextStyle = AppThemeHolder.textStyle.content.copy(
        fontSize = 12.sp,
        color = AppThemeHolder.colors.txtColor.copy(.6f)
    ),
    annotatedStyle: SpanStyle = SpanStyle(color = AppThemeHolder.colors.appColor),
    annotatedActions: List<AnnotatedAction> = listOf()
) {
    val regexTag = annotatedActions.map { it.regex }
    val regex = regexTag.joinToString("|")

    val pattern = Pattern.compile(regex)
    val length = text.length
    val annotationText = buildAnnotatedString {
        val matcher = pattern.matcher(text)
        var startIndex = 0
        while (matcher.find()) {
            append(text.subSequence(startIndex, matcher.start()).toString())
            pushStringAnnotation(
                tag = matcher.group(),
                annotation = matcher.group()
            )
            withStyle(
                style = annotatedStyle
            ) {
                append(matcher.group())
            }
            startIndex = matcher.end()
            pop()

        }
        if (startIndex < length) {
            append(text.subSequence(startIndex, length).toString())
        }
    }

    ClickableText(
        modifier = modifier,
        text = annotationText,
        style = textStyle,
        onClick = { offset ->
            annotatedActions.forEach { annotated ->
                val action = annotated.action
                val pattern = Pattern.compile(annotated.regex)
                val matcher = pattern.matcher(annotationText)
                if (matcher.find()) {
                    val tag = matcher.group()
                    annotationText.getStringAnnotations(
                        tag = tag,
                        start = offset,
                        end = offset
                    ).firstOrNull()?.let { annotation ->
                        action?.invoke(annotation.item)
                    }
                }

            }
        }
    )
}

data class AnnotatedAction(
    val regex: String,
    val action: ((match: String) -> Unit)? = null,
)